package org.szgb.console.zx.plan.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.szgb.console.sys.department.mapper.SysDepartmentMapper;
import org.szgb.console.sys.line.entity.SysLineLocation;
import org.szgb.console.sys.line.entity.SysLineLocationSystemEquipment;
import org.szgb.console.sys.line.mapper.SysLineLocationSystemEquipmentMapper;
import org.szgb.console.sys.todo.mapper.SysTodoMapper;
import org.szgb.console.sys.todo.service.SysTodoService;
import org.szgb.console.sys.user.entity.SysUser;
import org.szgb.console.sys.user.mapper.SysUserMapper;
import org.szgb.console.utils.Page;
import org.szgb.console.utils.UUIDUtil;
import org.szgb.console.wecom.robot.service.WeComRobotService;
import org.szgb.console.zx.plan.entity.ZxPlan;
import org.szgb.console.zx.plan.mapper.ZxPlanMapper;
import org.szgb.console.zx.task.entity.ZxTask;
import org.szgb.console.zx.task.entity.ZxTaskForm;
import org.szgb.console.zx.task.mapper.ZxTaskFormMapper;
import org.szgb.console.zx.task.mapper.ZxTaskMapper;
import org.szgb.core.base.entity.ApprovalDto;
import org.szgb.core.base.entity.BeanEntity;

import java.io.IOException;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ZxPlanService {
    private final ZxPlanMapper zxPlanMapper;
    private final SysUserMapper sysUserMapper;
    private final ZxTaskMapper zxTaskMapper;
    private final ZxTaskFormMapper zxTaskFormMapper;
    private final SysLineLocationSystemEquipmentMapper sysLineLocationSystemEquipmentMapper;
    private final SysDepartmentMapper sysDepartmentMapper;
    private final SysTodoMapper sysTodoMapper;

    private final SysTodoService sysTodoService;
    private final WeComRobotService weComRobotService;

    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    @Autowired
    public ZxPlanService(ZxPlanMapper zxPlanMapper, SysUserMapper sysUserMapper, SysTodoService sysTodoService, ZxTaskMapper zxTaskMapper, ZxTaskFormMapper zxTaskFormMapper, SysLineLocationSystemEquipmentMapper sysLineLocationSystemEquipmentMapper, SysDepartmentMapper sysDepartmentMapper, WeComRobotService weComRobotService, SysTodoMapper sysTodoMapper) {
        this.zxPlanMapper = zxPlanMapper;
        this.sysUserMapper = sysUserMapper;
        this.sysTodoService = sysTodoService;
        this.zxTaskMapper = zxTaskMapper;
        this.zxTaskFormMapper = zxTaskFormMapper;
        this.sysLineLocationSystemEquipmentMapper = sysLineLocationSystemEquipmentMapper;
        this.sysDepartmentMapper = sysDepartmentMapper;
        this.weComRobotService = weComRobotService;
        this.sysTodoMapper = sysTodoMapper;
    }

    @Transactional(readOnly = true)
    public ZxPlan get(String id) {
        return zxPlanMapper.get(id);
    }

    @Transactional(readOnly = true)
    public List<ZxPlan> findList(ZxPlan zxPlan) {
        if (zxPlan != null && zxPlan.getPageDto() != null) {
            Page<ZxPlan> page = new Page<>(zxPlan.getPageDto());
            page.setFirst((page.getPageNo() - 1) * page.getPageSize());
            zxPlan.setPage(page);
        }
        return zxPlanMapper.findList(zxPlan);
    }

    @Transactional(readOnly = true)
    public Integer getCount(ZxPlan zxPlan) {
        return zxPlanMapper.getCount(zxPlan);
    }

    @Transactional()
    public void save(ZxPlan zxPlan) {
        // 检查实体对象的ID是否为null，判断是否为新实体
        if (zxPlan.getId() == null || zxPlan.getId().isEmpty()) {
            // 对于新实体，设置创建者信息
            zxPlan.setCreatedBy(zxPlan.getUpdatedBy());
            // 添加UUID
            zxPlan.setId(UUIDUtil.getUUID());
            // 执行插入操作
            zxPlanMapper.insert(zxPlan);
            // 返回成功插入的信息
        } else {
            // 执行更新操作
            zxPlanMapper.update(zxPlan);
        }
    }

    @Transactional
    public void delete(String ids) {
        String[] idArray = ids.split(",");
        for (String id : idArray) {
            ZxTask task = new ZxTask();
            task.setZxPlan(new ZxPlan(id));
            List<ZxTask> zxTaskList = zxTaskMapper.findList(task);
            String[] array = zxTaskList.stream().map(BeanEntity::getId).toArray(String []::new);
            // 删除任务
            zxTaskMapper.delete(array);
            // 删除任务表单
            zxTaskFormMapper.deleteByTaskId(array);
            // 删除任务待办
            sysTodoMapper.deleteByParameter(array);
        }
        // 删除计划
        zxPlanMapper.delete(idArray);
        // 删除计划待办
        sysTodoMapper.deleteByParameter(idArray);
    }

    @Transactional
    public void create(ZxPlan zxPlan) throws IOException, InterruptedException {
        zxPlan.setStatus(0);
        // 设置实体对象的更新者为当前用户
        // 调用服务层的save方法，尝试保存或更新实体对象，返回保存结果的Map
        this.save(zxPlan);
        // 向工班长发送待办
        List<SysUser> foremanList = sysUserMapper.getUserInDepartmentWithRole(zxPlan.getResponsible().getId(), "45b016b7-f50e-44ea-84b4-c70462459c1d");
        sysTodoService.createTodoAndRobotSend(1, 3, foremanList, zxPlan.getId(), "【" + zxPlan.getName() + "】专项计划待处理", "专项计划待处理，牵头人待派发");
    }


    @Transactional
    public void setLeader(ZxPlan zxPlan) throws IOException, InterruptedException {
        zxPlan.setStatus(1);
        zxPlanMapper.update(zxPlan);
        ZxPlan plan = zxPlanMapper.get(zxPlan.getId());

        String[] equipmentIds = plan.getEquipmentIds().split(",");
        List<String> units = plan.getUnit() != null ? Arrays.asList(plan.getUnit().split(",")) : Collections.singletonList(null);
        List<SysUser> userList = sysUserMapper.getUserInDepartmentWithRole(plan.getResponsible().getId(), "b157bbc6-e4e0-4587-a4c4-bc4dced82475");

        AtomicInteger massageNum = new AtomicInteger();
        AtomicReference<String> massage = new AtomicReference<>("");

        // 处理待办
        sysTodoService.approval(plan.getId(), plan.getUpdatedBy().getId());

        List<SysUser> userArrayList = new ArrayList<>();
        userArrayList.add(sysUserMapper.get(plan.getLeader().getId()));
        sysTodoService.createTodoAndRobotSend(7, 1, userArrayList, plan.getId(), "【" + plan.getName() + "】专项计划已下发", "该专项已指定牵头人为您");

        // 收集所有 CompletableFuture
        List<CompletableFuture<Void>> futures = new ArrayList<>();

        Arrays.stream(plan.getSubstationIds().split(",")).forEach(locationId -> {
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                ZxTask zxTask = new ZxTask();
                zxTask.setId(UUIDUtil.getUUID());
                zxTask.setZxPlan(plan);
                zxTask.setStatus(0);
                zxTask.setLocation(new SysLineLocation(locationId));
                zxTask.setUpdatedBy(new SysUser("1"));
                zxTask.setCreatedBy(zxTask.getUpdatedBy());

                List<ZxTaskForm> zxTaskFormList = new ArrayList<>();
                units.forEach(unit -> {
                    List<SysLineLocationSystemEquipment> sysLineLocationSystemEquipmentList =
                            sysLineLocationSystemEquipmentMapper.findByEquipmentIdArrayWithLocationId(locationId, equipmentIds);

                    if (sysLineLocationSystemEquipmentList != null && !sysLineLocationSystemEquipmentList.isEmpty()) {
                        String[] equipmentArray = sysLineLocationSystemEquipmentList.stream()
                                .map(SysLineLocationSystemEquipment::getId).toArray(String[]::new);

                        for (String equipmentId : equipmentArray) {
                            ZxTaskForm zxTaskForm = new ZxTaskForm();
                            zxTaskForm.setId(UUIDUtil.getUUID());
                            zxTaskForm.setTask(zxTask);
                            zxTaskForm.setEquipment(new SysLineLocationSystemEquipment(equipmentId));
                            if (unit != null) {
                                zxTaskForm.setUnit(unit);
                            }
                            zxTaskForm.setIsFinish(false);
                            zxTaskForm.setIsAbnormal(false);
                            zxTaskForm.setUpdatedBy(new SysUser("1"));
                            zxTaskForm.setCreatedBy(zxTaskForm.getUpdatedBy());
                            zxTaskFormList.add(zxTaskForm);
                        }
                    }
                });

                if (!zxTaskFormList.isEmpty()) {
                    zxTaskFormMapper.insertBatch(zxTaskFormList);
                    zxTaskMapper.insert(zxTask);

                    String[] userIds = userList.stream().map(SysUser::getId).toArray(String[]::new);
                    ZxTask task = zxTaskMapper.get(zxTask.getId());
                    String title = "【" + task.getZxPlan().getName() + "】专项任务待处理";

                    // ✅ 递增计数器
                    massageNum.incrementAndGet(); // 或 getAndIncrement()，但建议用 incrementAndGet()
                    // ✅ 设置消息内容（注意：多个任务会覆盖！）
                    String startDate = task.getZxPlan().getStartAt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                    String endDate = task.getZxPlan().getEndAt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                    String content = "【" + task.getLocation().getName() + "】专项待下发，时间" + startDate + "~" + endDate;

                    if (massage.get().isEmpty()) {
                        massage.set(title + content);
                    }
                    sysTodoService.asyncCreateTodo(8, 3, userIds, zxTask.getId(), title, content);
                }
            });
            futures.add(future); // 添加到列表
        });

        CompletableFuture<Void> allDone = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
                .thenRun(() -> {
                    // 这个回调会在所有任务完成后自动执行（在 ForkJoinPool 线程中）
                    if (massageNum.get() > 0) {
                        String finalMessage = massage.get() + "。共" + massageNum.get() + "条任务";
                        try {
                            weComRobotService.sendText(finalMessage,
                                    userList.stream().map(SysUser::getUsername).toArray(String[]::new));
                        } catch (Exception e) {
                            // 记录日志，避免回调失败影响系统
                            log.error("发送企业微信消息失败", e);
                        }
                    }
                });
    }

    @Transactional
    public void foremanApproval(ApprovalDto approvalDto, ZxPlan zxPlan) throws IOException, InterruptedException {
        // 处理待办
        sysTodoService.approval(approvalDto.getId(), zxPlan.getUpdatedBy().getId());

        if (approvalDto.getIsApproval()) {
            // 更改计划状态为工长通过
            zxPlan.setStatus(3);
            zxPlanMapper.update(zxPlan);
            // 发送给技术管理审批
            ArrayList<SysUser> userArrayList = new ArrayList<>();
            userArrayList.add(sysUserMapper.get(zxPlan.getCreatedBy().getId()));
            sysTodoService.createTodoAndRobotSend(5, 1, userArrayList, zxPlan.getId(), "【" + zxPlan.getName() + "】专项计划待处理", "专项计划已完成请尽快审批");
        } else {
            // 设置状态为已完成
            zxPlan.setStatus(1);
            zxPlanMapper.update(zxPlan);
            // 退回给牵头人
            List<SysUser> sysUserList = new ArrayList<>();
            sysUserList.add(sysUserMapper.get(zxPlan.getLeader().getId()));
            sysTodoService.createTodoAndRobotSend(7, 1, sysUserList, zxPlan.getId(), "【" + zxPlan.getName() + "】专项计划待处理", "专项计划已退回请尽快处理\n原因：" + approvalDto.getRemark());
        }
    }

    @Transactional
    public void supervisorApproval(ApprovalDto approvalDto, ZxPlan zxPlan) throws IOException, InterruptedException {
        // 处理待办
        sysTodoService.approval(approvalDto.getId(),zxPlan.getUpdatedBy().getId());

        if (approvalDto.getIsApproval()) {
            // 更改计划状态为技管通过
            zxPlan.setStatus(4);
            zxPlanMapper.update(zxPlan);
            // 发送给主任知会
            List<SysUser> list = sysUserMapper.getUserInDepartmentWithRole(sysDepartmentMapper.get(zxPlan.getResponsible().getId()).getParent().getId(), "992b876c-1da9-4268-8b8c-5fd965698cf8");
            sysTodoService.createTodoAndRobotSend(6, 1, list, zxPlan.getId(), "【" + zxPlan.getName() + "】专项计划待处理", "专项计划已完成请知会");
        } else {
            // 状态退回给工班长
            zxPlan.setStatus(2);
            zxPlanMapper.update(zxPlan);
            // 重新发送待办给工班长
            List<SysUser> foremanList = sysUserMapper.getUserInDepartmentWithRole(zxPlan.getResponsible().getId(), "45b016b7-f50e-44ea-84b4-c70462459c1d");
            sysTodoService.createTodoAndRobotSend(4, 3, foremanList, zxPlan.getId(), "【" + zxPlan.getName() + "】专项计划待处理", "专项计划已退回请尽快处理\n原因：" + approvalDto.getRemark());

        }
    }
}
